package com.codermn.并发访问控制.阻塞队列;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * <p>
 *     借助同步阻塞队列，也可以实现并发控制的效果，比如队列中初始化n个元素，每次消费从队列中获取一个元素，
 *     如果拿不到则阻塞；执行完毕之后，重新塞入一个元素，这样就可以实现一个简单版的并发控制
 *     demo版演示，下面指定队列长度为2，表示最大并发数控制为2；设置为1时，可以实现单线程的访问控制
 * </p>
 * @author jxau_scf
 * @date 2021/8/13 - 10:36
 */
public class Demo {
    AtomicInteger cnt = new AtomicInteger();
    private void consumer(LinkedBlockingQueue<Integer> queue){
        try {
            //同步阻塞拿数据
            Integer val = queue.take();
            Thread.sleep(2000);
            System.out.println("成功拿到：" + val + "Thread:" + Thread.currentThread());

        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            //添加数据
            System.out.println("结束" + Thread.currentThread());
            System.out.println("添加数据"+queue.offer(cnt.getAndAdd(1)));
        }
    }

    public void blockQueue() throws InterruptedException {
        LinkedBlockingQueue<Integer> queue = new LinkedBlockingQueue<>();
        queue.add(cnt.getAndAdd(1));
//        queue.add(cnt.getAndAdd(1));


        new Thread(()->consumer(queue)).start();
        new Thread(()->consumer(queue)).start();
        new Thread(()->consumer(queue)).start();
        new Thread(()->consumer(queue)).start();
        Thread.sleep(10000);
    }
}
